package org.as4game.common.utils
{
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	
	/**
	 * 键盘状态记录
	 * 
	 * @auther hproof
	 */
	public class KeyboardState
	{
		private var m_states:Array;
		
		/**
		 * 初始化键盘状态
		 * 
		 * @param eventDispatcher 用来接收键盘消息
		 */
		public function KeyboardState( eventDispatcher:IEventDispatcher )
		{
			m_states = [];
			
			eventDispatcher.addEventListener( KeyboardEvent.KEY_DOWN, onKeyEvent);
			eventDispatcher.addEventListener( KeyboardEvent.KEY_UP, onKeyEvent);
		}
		
		// 键盘消息, 记录
		private function onKeyEvent(event:KeyboardEvent ):void{
			
			var keyCode:uint = event.keyCode;
			for( var i:int = 0; i<m_states.length; i++){
				if( m_states[i] == keyCode ){
					if( event.type == KeyboardEvent.KEY_DOWN ) return;
					m_states[i] = m_states[m_states.length-1];
					-- m_states.length;
					break;
				}
			} 
			if( event.type == KeyboardEvent.KEY_DOWN ){
				m_states.push( keyCode );
			}
		}
		
		/**
		 * 清空状态
		 */
		public function reset():void{
			m_states.length = 0;
		}
		
		
		/**
		 * 返回当前的键盘按键状态, [keyCode, keyCode, ...]
		 */
		public function get status():Array{
			return m_states;
		}
		
		/**
		 * 返回当前的键盘按键状态的字符串形式
		 */
		public function get status_string():String{
			return String.fromCharCode.apply(null, m_states );
		}
		
		/**
		 * 是否按下了某个键
		 */
		public function is_key_down( keyCode:uint ):Boolean{
			return m_states.indexOf( keyCode ) >= 0;
		}
		public function is_key_down_str( key:String ):Boolean{
			return status_string.indexOf( key ) >= 0;
		}
		
		/**
		 * 获取平移量
		 */
		public function getTranslateMatrix( val_move:Number=0.2 ):Matrix3D{
			var m:Matrix3D = new Matrix3D();
			var status:Array = this.status;
			
			if( status && status.length ){
				if( is_key_down( 16 ) ) {		// shift key
					val_move *= 10;
				}
				if( is_key_down( 17 ) ){		// ctrl key
				}
				for each(var keyCode:uint in status){
					var keyChar:String = String.fromCharCode( keyCode );
					switch( keyChar ){
						case 'W': m.appendTranslation(0, 0, -val_move); break;
						case 'S': m.appendTranslation(0, 0, val_move); break;
						case 'A': m.appendTranslation(-val_move, 0, 0); break;
						case 'D': m.appendTranslation(val_move, 0, 0); break;
					}
				}
			}
			
			return m;
		}
		
		/**
		 * 根据当前的输入状态, 获取 变化矩阵
		 * @param val_move 单位移动量
		 * @param val_rotate 单位转动量
		 */
		public function getMoveMatrix( val_move:Number=0.2, val_rotate:Number=12 ):Matrix3D{
			var m:Matrix3D = new Matrix3D();
			var status:Array = this.status;
			
			if( status && status.length ){
				if( is_key_down( 16 ) ) {		// shift key
					val_move *= 10;
					val_rotate *= 4;
				}
				if( is_key_down( 17 ) ){		// ctrl key
				}
				for each(var keyCode:uint in status){
					var keyChar:String = String.fromCharCode( keyCode );
					switch( keyChar ){
						case 'W': m.appendTranslation(0, 0, -val_move); break;
						case 'S': m.appendTranslation(0, 0, val_move); break;
						case 'A': m.appendRotation(val_rotate, Vector3D.Y_AXIS); break;
						case 'D': m.appendRotation(-val_rotate, Vector3D.Y_AXIS); break;
						case 'Q': m.appendTranslation(-val_move, 0, 0); break;
						case 'E': m.appendTranslation(+val_move, 0, 0); break;
						case 'F': m.appendTranslation(0, val_move, 0); break;
						case 'R': m.appendTranslation(0, -val_move, 0); break;
					}
				}
			}
			
			return m;
		}
	}
}